package m3f.io;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class MatrixReaderFactory {
	
	public static MatrixReader newInstance(String file, boolean normalize){
		MatrixReader mr;
		try{
			InputStreamReader reader = new InputStreamReader(new FileInputStream(file));
			BufferedReader bReader = new BufferedReader(reader);
			
			String line = bReader.readLine();
			
			// Sparse ImageCLEF Matrix Reader Test
			try{
				String[] parts = line.split(" ");
				String[] parts2 = bReader.readLine().split(" ");;
				if(parts.length == 2 && parts.length != parts2.length){
					System.out.println(file + " is a sparse matrix file in ImageCLEF format");
					bReader.close();
					mr = new SparseImageCLEFMatrixReader();
					mr.normalizeVectors(normalize);
					return mr;
				}
			}catch(Exception e){}
			
			// Sparse Matrix Reader Test
			try{
				String[] parts = line.split(" ");
				for(int k = 1; k < parts.length; k++){
					String[] values = parts[k].split(":");
					Integer.parseInt(values[0]);
					Double.parseDouble(values[1]);
				}
				if(parts.length > 1){
					System.out.println(file + " is a sparse matrix file");
					bReader.close();
					mr = new SparseMatrixReader();
					mr.normalizeVectors(normalize);
					return mr;
				}
			}catch(Exception e){}
			// Triplets Matrix Reader Test
			try{
				String values[] = line.split(" ");
				if (values.length != 3) throw new Exception();
				new Triplet(values);
				System.out.println(file + " is a sparse matrix file in triplets format");
				bReader.close();
				mr = new TripletsMatrixReader();
				mr.normalizeVectors(normalize);
				return mr;
			}catch(Exception e){}
			// Dense Matrix Reader Test
			try{
				String values[] = line.split(" ");
				for(int i = 0; i < values.length; i++){
					Double.parseDouble(values[i]);
				}
				System.out.println(file + " is a dense matrix file");
				bReader.close();
				mr = new DenseMatrixReader();
				mr.normalizeVectors(normalize);
				return mr;
			}catch(Exception e){}
			// Binary Matrix Reader Test
			try{
				DataInputStream in = new DataInputStream(new FileInputStream(file));
				int columns = in.readInt();
				int checkCounter = 0;
				for(int i = 0; i < columns; i++){
					in.readInt();
					double v = in.readDouble();
					if(!Double.isNaN(v)){
						checkCounter++;
					}
				}
				in.close();
				if(checkCounter == columns){
					System.out.println(file + " is a sparse matrix file in binary format");
					mr = new BinaryMatrixReader();
					mr.normalizeVectors(normalize);
					return mr;
				}
			}catch(Exception e){}
		}catch(IOException ioe){
			System.err.println("A problem has been found with this file: " + file);
			ioe.printStackTrace();
		}
		return null;
	}
}
